package repository

import (
	"encoding/json"

	"gitee.com/li-zhenyi/yi-nian-zhi-jian/backend/internal/model"
	"gorm.io/gorm"
)

// AdventureRepository 历练仓库接口
// 定义历练数据访问的所有方法
type AdventureRepository interface {
	// 创建历练记录
	Create(record *model.AdventureRecord) error
	// 根据ID获取历练记录
	GetByID(id int64) (*model.AdventureRecord, error)
	// 获取用户的历练记录列表
	GetByUserID(userID int64, limit int) ([]*model.AdventureRecord, error)
	// 获取用户最近的历练
	GetLatestByUserID(userID int64) (*model.AdventureRecord, error)
	// 更新历练记录
	Update(record *model.AdventureRecord) error
	// 统计用户历练次数
	CountByUserID(userID int64) (int64, error)
}

// adventureRepository 实现AdventureRepository接口
type adventureRepository struct {
	db *gorm.DB
}

// NewAdventureRepository 创建历练仓库实例
func NewAdventureRepository(db *gorm.DB) AdventureRepository {
	return &adventureRepository{db: db}
}

// Create 创建历练记录
func (r *adventureRepository) Create(record *model.AdventureRecord) error {
	return r.db.Create(record).Error
}

// GetByID 根据ID获取历练记录
func (r *adventureRepository) GetByID(id int64) (*model.AdventureRecord, error) {
	var record model.AdventureRecord
	if err := r.db.First(&record, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &record, nil
}

// GetByUserID 获取用户的历练记录列表
func (r *adventureRepository) GetByUserID(userID int64, limit int) ([]*model.AdventureRecord, error) {
	var records []*model.AdventureRecord
	query := r.db.Where("user_id = ?", userID).Order("created_at DESC")
	
	if limit > 0 {
		query = query.Limit(limit)
	}
	
	if err := query.Find(&records).Error; err != nil {
		return nil, err
	}
	return records, nil
}

// GetLatestByUserID 获取用户最近的历练
func (r *adventureRepository) GetLatestByUserID(userID int64) (*model.AdventureRecord, error) {
	var record model.AdventureRecord
	if err := r.db.Where("user_id = ?", userID).
		Order("created_at DESC").
		First(&record).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &record, nil
}

// Update 更新历练记录
func (r *adventureRepository) Update(record *model.AdventureRecord) error {
	return r.db.Save(record).Error
}

// CountByUserID 统计用户历练次数
func (r *adventureRepository) CountByUserID(userID int64) (int64, error) {
	var count int64
	if err := r.db.Model(&model.AdventureRecord{}).
		Where("user_id = ?", userID).
		Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

// Helper functions for JSON conversion

// EncodeChoices 将选择列表编码为JSON字符串
func EncodeChoices(choices []model.AdventureChoice) (string, error) {
	data, err := json.Marshal(choices)
	if err != nil {
		return "", err
	}
	return string(data), nil
}

// DecodeChoices 将JSON字符串解码为选择列表
func DecodeChoices(data string) ([]model.AdventureChoice, error) {
	var choices []model.AdventureChoice
	if err := json.Unmarshal([]byte(data), &choices); err != nil {
		return nil, err
	}
	return choices, nil
}

// EncodeReward 将奖励编码为JSON字符串
func EncodeReward(reward model.AdventureReward) (string, error) {
	data, err := json.Marshal(reward)
	if err != nil {
		return "", err
	}
	return string(data), nil
}

// DecodeReward 将JSON字符串解码为奖励
func DecodeReward(data string) (*model.AdventureReward, error) {
	var reward model.AdventureReward
	if err := json.Unmarshal([]byte(data), &reward); err != nil {
		return nil, err
	}
	return &reward, nil
}
